﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using EFBasic.Configurations;
using EFBasic.Entities;
using EFBasic.Map;
using EFBasic.Migrations;

namespace EFBasic
{
    public class SchoolContext : DbContext
    {
        //public SchoolContext() : base() // No parameter, DB name is {Namespace}.{Context class name}
        //{
        //}

        //public SchoolContext() : base("MySchoolDB") // Database name
        //{
        //}

        public SchoolContext() : base("name=SchoolDBConnectionString") // Connection string with 'name=<connectionstringname>'
        {
            //Database.SetInitializer<SchoolContext>(new CreateDatabaseIfNotExists<SchoolContext>());

            //Database.SetInitializer<SchoolDBContext>(new DropCreateDatabaseIfModelChanges<SchoolDBContext>());
            //Database.SetInitializer<SchoolDBContext>(new DropCreateDatabaseAlways<SchoolDBContext>());
            //Database.SetInitializer<SchoolContext>(new SchoolDBInitializer()); // Custom DBInitializer

            Database.SetInitializer(new MigrateDatabaseToLatestVersion<SchoolContext, Configuration>("SchoolDBConnectionString")); // Enable-Migrations

            //Database.SetInitializer<SchoolContext>(null); // Disable initializer DB

            //Configuration.ProxyCreationEnabled = false; // Disable dynamic proxy 
            Configuration.AutoDetectChangesEnabled = true; // Auto detect change by Context
            // Configuration.LazyLoadingEnabled = false; // Disable lazy loading
        }

        public DbSet<Student> Students { get; set; }
        public DbSet<Standard> Standards { get; set; }

        public DbSet<User> Users { get; set; }
        public DbSet<UserTPT> UserTpts { get; set; }

        //////////////////// Configure table, column
        //protected override void OnModelCreating(DbModelBuilder modelBuilder)
        //{
        //    //// Fluent API > data annotations > default conventions.

        //    //Configure default schema
        //    modelBuilder.HasDefaultSchema("Admin");

        //    // Mapping entity to multiple tables
        //    modelBuilder.Entity<Student>().Map(m =>
        //    {
        //        m.Properties(p => new { p.StudentId, p.StudentName });
        //        m.ToTable("StudentInfo");

        //    }).Map(m =>
        //    {
        //        m.Properties(p => new { p.StudentId, p.Height, p.Weight, p.Photo, p.DateOfBirth });
        //        m.ToTable("StudentInfoDetail");

        //    });

        //    // Map entity to table
        //    modelBuilder.Entity<Student>().ToTable("StudentInfo");
        //    modelBuilder.Entity<Standard>().ToTable("StandardInfo", "dbo");

        //    //////////////////////////////
            
        //    // Configure primary key
        //    modelBuilder.Entity<Student>().HasKey<int>(s => s.StudentId);
        //    modelBuilder.Entity<Standard>().HasKey<int>(s => s.StandardId);

        //    // Configure composite primary key
        //    //modelBuilder.Entity<Student>().HasKey<int>(s => new { s.StudentId, s.StudentName }); 

        //    // Configure column
        //    modelBuilder.Entity<Student>()
        //                .Property(p => p.DateOfBirth)
        //                .HasColumnName("DoB")
        //                .HasColumnOrder(3)
        //                .HasColumnType("datetime2");

        //    //Configure Null Column
        //    modelBuilder.Entity<Student>()
        //            .Property(p => p.Height)
        //            .IsOptional();

        //    //Configure NotNull Column
        //    modelBuilder.Entity<Student>()
        //           .Property(p => p.Weight)
        //           .IsRequired();

        //    //Set StudentName column size to 50
        //    modelBuilder.Entity<Student>()
        //            .Property(p => p.StudentName)
        //            .HasMaxLength(50);

        //    //Set StudentName column size to 50 and change datatype to nchar 
        //    //IsFixedLength() change datatype from nvarchar to nchar
        //    modelBuilder.Entity<Student>()
        //            .Property(p => p.StudentName)
        //            .HasMaxLength(50).IsFixedLength();

        //    //Set size decimal(2,2)
        //    modelBuilder.Entity<Student>()
        //           .Property(p => p.Height)
        //           .HasPrecision(2, 2);

        //    //Set StudentName as concurrency column
        //    modelBuilder.Entity<Student>()
        //            .Property(p => p.StudentName)
        //            .IsConcurrencyToken();

        //    // or use
        //    modelBuilder.Entity<Student>()
        //        .Property(p => p.RowVersion)
        //        .IsRowVersion();

        //    base.OnModelCreating(modelBuilder);
        //}

        /////////// Mapping one-to-one
        //protected override void OnModelCreating(DbModelBuilder modelBuilder)
        //{
        //    // Configure StudentId as PK for StudentAddress
        //    modelBuilder.Entity<StudentAddress>()
        //        .HasKey(e => e.StudentId);

        //    // Configure StudentId as FK for StudentAddress
        //    modelBuilder.Entity<Student>()
        //                .HasOptional(s => s.StudentAddress) // Mark StudentAddress is optional for Student
        //                .WithRequired(ad => ad.Student); // Create inverse relationship, required student as primary key

        //    // Configure one-to-many
        //    modelBuilder.Entity<Student>()
        //        .HasRequired(s => s.Standard)
        //        .WithMany(s => s.Students)
        //        .HasForeignKey(s => s.StudentId);

        //    // or one-to-many
        //    modelBuilder.Entity<Standard>()
        //                .HasMany<Student>(s => s.Students)
        //                .WithRequired(s => s.Standard)
        //                .HasForeignKey(s => s.StandardId);

        //    // one-to-many with nullable column
        //    modelBuilder.Entity<Student>()
        //                .HasOptional<Standard>(s => s.Standard)
        //                .WithMany(s => s.Students)
        //                .HasForeignKey(s => s.StandardId);

        //    // many-to-many
        //    modelBuilder.Entity<Student>()
        //        .HasMany<Course>(s => s.Courses)
        //        .WithMany(c => c.Students)
        //        .Map(cs =>
        //             {
        //                 cs.MapLeftKey("StudentRefId");
        //                 cs.MapRightKey("CourseRefId");
        //                 cs.ToTable("StudentCourse");
        //             });

        //    base.OnModelCreating(modelBuilder);
        //}

        /////////////////////////// Move configuration
        //protected override void OnModelCreating(DbModelBuilder modelBuilder)
        //{
        //    // Moved all Student related configuration to StudentEntityConfiguration class
        //    modelBuilder.Configurations.Add(new StudentEntityConfiguration());
        //    base.OnModelCreating(modelBuilder);
        //}
    }
}
